package at.codebase.web.servlets.ajax;

import java.util.ArrayList;

import org.json.simple.JSONObject;

import at.codebase.core.log.Log;
import at.codebase.db.dao.EApiPartnerDao;
import at.codebase.db.dao.EItemDao;
import at.codebase.db.dao.EMessageDao;
import at.codebase.db.dao.EMessageExtDao;
import at.codebase.db.dao.EUserDao;
import at.codebase.db.entities.EApiPartner;
import at.codebase.db.entities.EItem;
import at.codebase.db.entities.EMessage;
import at.codebase.db.entities.EMessageExt;
import at.codebase.db.entities.EMessageExt.UserExt;
import at.codebase.db.entities.EUser;
import at.codebase.web.util.LocalRequest.RequestInformation;
import at.codebase.web.util.URLParameters.ParameterException;
import at.codebase.web.util.api.ApiPartnerCalls;
import at.codebase.web.util.json.JsonKeys;
import at.codebase.web.util.servlet.SecureAjaxServlet;

/**
 * 
 * @author Lukas Pfeifhofer <lukas.pfeifhofer@devlabs.pro>
 *
 */
@SuppressWarnings("unchecked")
public class AjaxMessageService extends SecureAjaxServlet {
	
	// FIXME base class?
	private static JSONObject errorObject;
	private static JSONObject successObject;
	
	static {
		successObject = new JSONObject();
		successObject.put(JsonKeys.STATUS, "success");
		
		errorObject = new JSONObject();
		errorObject.put(JsonKeys.STATUS, "error");
	}
	
	@Override
	protected void initSecurityLevels(ArrayList<UserLevel> secLevels) {
		secLevels.add(UserLevel.ADMIN);
		secLevels.add(UserLevel.REGISTERED);
	}
	
	@Override
	protected void processRequestSecurityLevel(RequestInformation requestInfo, UserLevel level, RequestType requestType) {
		
		try {
			String actionType = requestInfo.getParameters().getString("type");
			if(actionType.equals("sendMessage") && requestType.equals(RequestType.POST)){
				if(!tokenCorrect(requestInfo)) {
					JSONObject result = (JSONObject) errorObject.clone();
					result.put("randomKey", nextToken());
					writer().printInsecure(result.toJSONString());	
					return;
				}
				
				long recipientId = requestInfo.getParameters().getLong("recipient");
				EUser recipient = EUserDao.getUserById(new Long(recipientId)); 
				String messageContent = requestInfo.getParameters().getString("message");
				
				if (recipient != null && messageContent != null
						&& !messageContent.trim().equals("") && recipientId != requestInfo.getUser().getId().longValue()) {
					EItem item = null;
					if (requestInfo.getParameters().isExisting("item")) {
						long itemId = requestInfo.getParameters().getLong("item");
						item = EItemDao.getItemById(new Long(itemId));
					}
					EMessage message = null;

					if (item == null) {
						message = EMessage.createPrivateMessage(
								EUser.ref(requestInfo.getUser().getId()),
								EUser.ref(recipient.getId()), messageContent);
						Log.logMessage(requestInfo.getUser().getId(),
								"User (userid=" + requestInfo.getUser().getId()
										+ ") sent a message to (userid="
										+ recipientId + ")");
					} else {
						message = EMessage.createItemMessage(
								EUser.ref(requestInfo.getUser().getId()),
								EUser.ref(recipient.getId()), EItem.ref(item),
								messageContent);
						Log.logMessage(requestInfo.getUser().getId(),
								"User (userid=" + requestInfo.getUser().getId()
										+ ") sent a message to (userid="
										+ recipientId + ") item = (itemid="
										+ item.getId() + ")");
					}
					EMessageDao.addMessage(message);
					
					JSONObject result = (JSONObject) successObject.clone();
					result.put("randomKey", nextToken());
					writer().printInsecure(result.toJSONString());	
				} else {
					JSONObject result = (JSONObject) errorObject.clone();
					result.put("randomKey", nextToken());
					writer().printInsecure(result.toJSONString());	
					// TODO Logging? - User does not exists, same user or message is empty
				}
				
			}else if(actionType.equals("markRead") && requestType.equals(RequestType.POST)){
				String idsString = requestInfo.getParameters().getString("ids");
				String[] stringIds = idsString.split(",");
				ArrayList<Long> longIds = new ArrayList<Long>(); 
				for(int i = 0; i < stringIds.length; i++){
					long id = Long.parseLong(stringIds[i]);
					longIds.add(new Long(id));	
				}
				EMessageDao.markRead(longIds, requestInfo.getUser().getId());
				writer().printInsecure(successObject.toJSONString());
				
			}else if(actionType.equals("sendMultiMessage") && requestType.equals(RequestType.POST)){
				if(!tokenCorrect(requestInfo)) {
					JSONObject result = (JSONObject) errorObject.clone();
					result.put("randomKey", nextToken());
					writer().printInsecure(result.toJSONString());	
					return;
				}
				
				long[] recipientIds = requestInfo.getParameters().getLongArray("recipients");
				String messageContent = requestInfo.getParameters().getString("message");
				boolean nonValid = true;
				for(long recipientId:recipientIds){
					EUser recipient = EUserDao.getUserById(new Long(recipientId)); 
					
					if (recipient != null && messageContent != null
							&& !messageContent.trim().equals("") && recipientId != requestInfo.getUser().getId().longValue()) {
						EMessage message = null;

						message = EMessage.createPrivateMessage(
								EUser.ref(requestInfo.getUser().getId()),
								EUser.ref(recipient.getId()), messageContent);
						EMessageDao.addMessage(message);
						Log.logMessage(requestInfo.getUser().getId(),
								"User (userid=" + requestInfo.getUser().getId()
										+ ") sent a message to (userid="
										+ recipientId + ")");
						nonValid = false;
					}
				}
				if(!nonValid){
					JSONObject result = (JSONObject) successObject.clone();
					result.put("randomKey", nextToken());
					writer().printInsecure(result.toJSONString());	
				}else{
					JSONObject result = (JSONObject) errorObject.clone();
					result.put("randomKey", nextToken());
					writer().printInsecure(result.toJSONString());	
				}
				
			}else if(actionType.equals("sendMessageExt") && requestType.equals(RequestType.POST)){
				if(!tokenCorrect(requestInfo)) {
					JSONObject result = (JSONObject) errorObject.clone();
					result.put("randomKey", nextToken());
					writer().printInsecure(result.toJSONString());	
					return;
				}
				
				long partnerId = requestInfo.getParameters().getLong("partner");
				EApiPartner partner = EApiPartnerDao.getApiPartner(new Long(partnerId));

				if(partner != null){
				
					String extConversationId = requestInfo.getParameters().getString("extConversationId");
					String extUserId = requestInfo.getParameters().getString("extUserId");
					String extUserName = requestInfo.getParameters().getString("extUserName");
					
					String recipientId = requestInfo.getParameters().getString("recipient");
					String messageContent = requestInfo.getParameters().getString("message");
					
					if (recipientId != null && messageContent != null
							&& !messageContent.trim().equals("") && !recipientId.trim().equals("")) {
						
						
						
						String itemKey = null;
						if (requestInfo.getParameters().isExisting("item")) {
							itemKey = requestInfo.getParameters().getString("item");
						}

						UserExt recipient = new UserExt(EApiPartner.ref(partner), extUserId, extUserName);
						EMessageExt message = null;
	
						if (itemKey == null) {
							message = EMessageExt.createPrivateOutgoingMessageExt(EUser.ref(requestInfo.getUser()), recipient, messageContent, extConversationId);
							JSONObject apiResult = ApiPartnerCalls.sendMessage(partner, message);
							
							if(apiResult != null && apiResult.get("success").equals(new Boolean(true))){
								
								EMessageExtDao.addMessage(message);
								
								JSONObject result = (JSONObject) successObject.clone();
								result.put("randomKey", nextToken());
								writer().printInsecure(result.toJSONString());	
							}else{
								JSONObject result = (JSONObject) errorObject.clone();
								result.put("randomKey", nextToken());
								writer().printInsecure(result.toJSONString());	
							}

							Log.logMessage(requestInfo.getUser().getId(),
									"User (userid=" + requestInfo.getUser().getId()
											+ ") sent a message to partner application");
						} else {
							message = EMessageExt.createItemOutgoingMessageExt(EUser.ref(requestInfo.getUser()), recipient, itemKey, messageContent, extConversationId);
							JSONObject apiResult = ApiPartnerCalls.sendMessage(partner, message);

							if(apiResult != null && apiResult.get("success").equals(new Boolean(true))){
								
								EMessageExtDao.addMessage(message);
								
								JSONObject result = (JSONObject) successObject.clone();
								result.put("randomKey", nextToken());
								writer().printInsecure(result.toJSONString());	
							}else{
								JSONObject result = (JSONObject) errorObject.clone();
								result.put("randomKey", nextToken());
								writer().printInsecure(result.toJSONString());	
							}

							Log.logMessage(requestInfo.getUser().getId(),
									"User (userid=" + requestInfo.getUser().getId()
											+ ") sent a message to partner application");
						}
					} else {
						JSONObject result = (JSONObject) errorObject.clone();
						result.put("randomKey", nextToken());
						writer().printInsecure(result.toJSONString());	
					}
				
				}else{
					JSONObject result = (JSONObject) errorObject.clone();
					result.put("randomKey", nextToken());
					writer().printInsecure(result.toJSONString());	
				}
				
			}
			/*
			else if(actionType.equals("itemData") && requestType.equals(RequestType.POST)){
				long partnerId = requestInfo.getParameters().getLong("partner");
				EApiPartner apiPartner = EApiPartnerDao.getApiPartner(new Long(partnerId));
				if(apiPartner != null){
					String itemKeyString = requestInfo.getParameters().getString("item");
					Key<EItem> itemKey = Key.create(itemKeyString);
					
					String itemTitle;
					String itemPrice;
					
					if(itemKey.getRaw().getAppId().equals(itemKey.getRaw().getAppId())){
						//OWN Item
						EItem item = EItemDao.getItemById(new Long(itemKey.getId()));
												
					}else{
						//Other Item
						JSONObject item = ApiPartnerCalls.getItem(apiPartner, String.valueOf(itemKey.getId()));
						System.out.println(item);
					}
					
					System.out.println(itemKey.getRaw().getAppId());
					
					System.out.println(EApiPartner.key(new Long(partnerId)).getRaw().getAppId());
					writer().printInsecure(errorObject.toJSONString());		
				}else{
					writer().printInsecure(errorObject.toJSONString());		
				}
			}
			*/
		} catch (ParameterException e) {
			writer().printInsecure(errorObject.toJSONString());
			//TODO: Wront parameter.. Maybe Log this
		}
		
	}

}
